package com.gt.wxpay;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.gt.wxpay.cashier.payChannel.domain.model.PayChannel;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import okhttp3.*;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * packageName com.cztech.platform.cashier.cashierNewTestPay
 *
 * @author GuoTong
 * @version JDK 8
 * @className cashierNewTestPay
 * @date 2024/3/13
 * @description TODO
 */
public class cashierNewTestPay {
    private Logger logger = LoggerFactory.getLogger(cashierNewTestPay.class);

    private Long testMid = 109L;


    private OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .callTimeout(60, TimeUnit.SECONDS)
            .build();
    private MediaType JSON = MediaType.get("application/json; charset=utf-8");


    @Test
    public void sendNotify(){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("notifyTime","123456454");
        // 通知事件
        RequestBody body = RequestBody.create(JSON,jsonObject.toJSONString() );
        System.out.println("Refund通知业务侧=body==>" + jsonObject.toJSONString());
        Request request = new Request.Builder()
                .url("http://10.130.1.71:8200/guide/guideOrder/notify/pay")
                .post(body)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                String responseData = response.body().string();
                System.out.println("Success"+responseData);
            } else {
                System.out.println("Fail:"+response.code());
            }

        } catch (IOException e) {
            // 通知失败---收银台会每隔6分钟通知一次，总共通知10次。
            e.printStackTrace();
        }
    }

    /**
     * 查询订单：WECHATPAY2-SHA256-RSA2048
     *
     * @param merchantId
     * @param appId
     * @param config
     * @throws Exception
     */
    private void queryByJSAPI(String merchantId, String appId, Config config) throws Exception {
        JsapiServiceExtension service =
                new JsapiServiceExtension.Builder()
                        .config(config)
                        .signType("RSA") // 不填默认为RSA
                        .build();
        com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest request = new com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest();
        request.setMchid(merchantId);
        request.setOutTradeNo("1768569710097530880");
        Transaction transaction = service.queryOrderByOutTradeNo(request);
        logger.info(transaction.toString());
        logger.info("查询订单金额：" + transaction.getAmount());
        if (transaction == null) {
            logger.error("查询订单失败");
        }
    }


    /**
     * 支付下单--创建订单{小程序}
     */
    @Test
    void paymentServiceDoOrderCreate() throws Exception {
        try {
            logger.info("输入1：小程序支付，输入2：Native二维码支付");
            String next = "3";
            logger.info("下单创建订单开始=" + LocalDateTime.now());
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            PayChannel payChannel = new PayChannel();
            // 获取证书资源
            String certPath = payChannel.getCertPath();
            // 获取 商户号
            String merchantId = payChannel.getMerchantId();
            // 商户证书序列号
            String merchantSerialNumber = payChannel.getMerchantSerialNumber();
            // 商户APIV3密钥 *
            String apiV3key = payChannel.getPrivateKey();
            String appId = payChannel.getAppId();
            String os = System.getProperty("os.name");
            if (os.toLowerCase().startsWith("win")) {
                certPath = "D:\\BaiduNetdiskDownload\\微信支付秘密\\apiclient_key.pem";
                merchantId = "wcV6jEy4hIqrbL7NtFJHhjYp3+PYh8vYSYhoeFyxKRlJ7/Q5vV0RZiBHl++zD4keC6oMXEwXDgUBMJnMqZyTwY7+ENfboFTsi0elfwxVIC2APiXr/XJEw7FmmejZynt1Zgmf3067JmoJT/ATUlHSIGYJh1HX6Fc+s7gG2xpY+UlyZV7FBGU1ejtBUkqWZX1aHSd886IdNWZZNZjr6cH2scDYV5KRlTO9i0Bu7du/kOw6TQBKipZeX1BfjzcWED9PdgIqad7xel8LRsj0XGXMhW8LfT9HQGQNg1PsPj+vl9KuxjX2WnQ5vJfckWRWjVt2/MjRU6FSIXxRyIGzuxw5oA==";
                merchantSerialNumber = "OjV3tqAOR08im+0qVMYa5XQ+BiY4F6KWZ9TsPEZOcgqeOm5ukexTmxUQLZs1iSUUVlS/BSKbjsQo6443CoZQUYwNMV7tcdwefZSNCVoGK/y3qWwCrDuMkKkalhyuWU6jVIUAtun+X07z+TkqYkJTYGQ+QOpX1oUmtdZv/H5+c8axNRQ91GZ1ug2Wdb3SH44wwIU5VKc4j2xwqsLgZgjibgqRAt8H0LqlJqHeyaZlddJto/r3ywcb8ZPDnBlJPj4XFUzmnWe/lgjyi4Hz8meYViCs0KL5d4jmmCLcGnOhxTLwX/j/iiMYRgTl4OUNV+vt5spUso+NFKtai8TkYZUSjg==";
                apiV3key = "c4gRDYtB6DAryazk9ERDdjCB9wLGrktyopChxL8g1kcb1+5VxnvpHWk6x+9pk6jb70bq0ld2dtpwMIH/VcSac7YdsZQvv8c+33T+tWHQ5qwoVG3P9crq0NXCt/vx6NWE231oJnAzF93kviCZnRqjxvHGMxvl0UXbxakqce7vgltWAhCQVfYvzIJ19Q9e667VxTmhxFC/RVmWOGlY6+VUPWTeddB/WAJKGce0RSDQioJfWbT6K+xIl0/1QD9mAPMvf6OCIMfoCOKYI5ZM0BXlATXhpv4Lp4u7mMCKNzSN+KNbvDf+IHB6DvCcVc9A3l7Cav/JVR9fwmGq2pb/wnrbrA==";
                appId = "F+YH+SfswKMvst6rvcl3q1kYwQHo725jR2OvDueVsgI8ONa2x3fby1dBtjE8pHWRMYgazCEjoD50kTpkLQtV4O1N/RuapWki0w4shsom1qSkn8W4D0AjlPpqQv8wLQmGY+0V79PEjxhTBJYyOe/EH4fglnqoeqR2YWVGXu9U1wrCI5FHOflbq3yGQSDXUqp46jB/+nUcGUg+PcIPARFTHoiJEJkTVZvrrZNpwKDJT1vJvDQowML14TOaMTYv+plhsobPYvyNDVDA1Whk+0Gp/GZm7LR4fGtptyc2UaZHrrlW4V9WUpyhUzB8V+7uYaPuxQDTcc3aMz5EUjqaK0eypQ==";
                merchantId = RSAExample.getStrByRSADecrypted(merchantId);
                merchantSerialNumber = RSAExample.getStrByRSADecrypted(merchantSerialNumber);
                apiV3key = RSAExample.getStrByRSADecrypted(apiV3key);
                appId = RSAExample.getStrByRSADecrypted(appId);
            }

            Config config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKeyFromPath(certPath)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3key)
                    .build();
            if (next.equals("1")) {
                sendJSAPI(merchantId, appId, config);
            }
            if (next.equals("2")) {
                senNativePay(merchantId, appId, config);
            }
            if (next.equals("3")) {
                queryByJSAPI(merchantId, appId, config);
            }
            stopWatch.stop();
            logger.info("下单创建订单执行执行时间（ms）：" + stopWatch.getTotalTimeMillis());
        } catch (Exception e) {
            logger.error("下单创建订单失败", e);
        }
    }

    /**
     * JSAPI下单
     *
     * @param merchantId
     * @param appId
     * @param config
     * @throws Exception
     */
    private void sendJSAPI(String merchantId, String appId, Config config) throws Exception {
        // JSAPI支付下单，并返回JSAPI调起支付数据
        JsapiServiceExtension service =
                new JsapiServiceExtension.Builder()
                        .config(config)
                        .signType("RSA") // 不填默认为RSA
                        .build();
        com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest request = new com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest();
        com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new com.wechat.pay.java.service.payments.jsapi.model.Amount();
        amount.setTotal(1);
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setAppid(appId);
        request.setMchid(merchantId);
        request.setDescription("测试商品标题");
        request.setTimeExpire(LocalDateTime.now().plusMinutes(30).toString() + "+08:00");
        request.setAttach("【附加数据】 附加数据实际情况下只有支付完成状态才会返回该字段");
        // 付款人
        Payer payer = new Payer();
        String openId = "b8VyVSiVHHs7SW1UWdgEhBPlaGvoRNXS7lghgFnvtyNbAAjrKTtsotAF6oC3oIvrfdcVUgxaZizp7328aHRoHD5BzrwkaFDlZp+EFPvGxtJqZ3XkJAnt88Td0wyVitUPPZCxFN9ZVO5TBgtxRs9OSYEuWR7VloXk6SULdQmMhgDGtKd0y7NrdJQMlACRWZUpq3i7WewFwiCD7eiyBMbFFQ5FhMeu/mKg6b/mUvddyJCkVR0Iska+UhfuHt5N7lPsvrYF+7uSSw3h2FZSKD+nTuCLGtCSm/Thpgf7WQWIwfx626rNukIZq7ovAR2cZT5xR3/tVeme0NzHPdZJTCxaqQ==";
        openId = RSAExample.getStrByRSADecrypted(openId);
        // 用户id
        payer.setOpenid(openId);
        request.setPayer(payer);
        request.setNotifyUrl("https://notify_url");
        // 使用雪花算法--生成唯一流水号
        String snowflakeNextIdStr = IdUtil.getSnowflakeNextIdStr();
        logger.error("我们侧的流水号：" + snowflakeNextIdStr);
        request.setOutTradeNo(snowflakeNextIdStr);
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        logger.info(response.toString());
        logger.info("签名：" + response.getPaySign());
        if (response == null) {
            logger.error("下单失败");
        }
    }

    /**
     * 本地支付
     *
     * @param merchantId
     * @param appId
     * @param config
     * @return
     */
    private PrepayResponse senNativePay(String merchantId, String appId, Config config) {
        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(1);
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setAppid(appId);
        request.setMchid(merchantId);
        request.setDescription("测试商品标题");
        request.setNotifyUrl("https://notify_url");
        request.setOutTradeNo(IdUtil.getSnowflakeNextIdStr());
        logger.info(request.toString());
        // 调用下单方法，得到应答
        PrepayResponse response = service.prepay(request);
        logger.info(response.toString());
        logger.info("微信支付二维码地址：" + response.getCodeUrl());
        if (response == null) {
            logger.error("下单失败");
        }
        return response;
    }


}
